Middleware systems are often used to support integration and interoperation of software programs having interfaces defined in a number of different notations. Notations for interface definition may take the form of a full-fledged programming language, such as Java, C++, ML, Lisp, etc., or may be special-purpose notations specifically for defining interfaces which may lack logic and other constructs necessary to fully define an executable program, such as CORBA Interface Definition Language (CORBA IDL).
Interoperation between software programs having interfaces defined in different notations requires the ability to define one or more interfaces in one notation for software programs having interfaces defined in another notation, so that a program may invoke an interface defined in the first notation to request and receive services of programs through interfaces defined in a second notation. Thus, for example, a C++ program may invoke a CORBA IDL interface that in turn causes a Java interface of a Java program to be invoked and provide services in response to the request of the C++ program.
Since different notations have different syntaxes and semantics, and vary considerably in their expressive power and built-in structures and functions, mapping interfaces defined in one notation to another is not always a straightforward matter. In particular, defining a generalized mapping of all interfaces definable in a first notation to interfaces in a second notation often results in cumbersome and unwieldy interfaces when the mapping is applied to interfaces commonly encountered in practice. For example, a simple interface in the first notation may map to a very complex interface in the second.
Certain differences in the treatment of data types exemplify this problem. Many notations differ in their treatment of specific data types with respect to run-time type checking versus compile-time type checking. For example, the Java data type java.util.Vector is commonly used as a parameter in an invocation or response to an invocation. Vector implements an array of objects which may be of any type, meaning that type definitions of the contents of a Vector are not required when the Vector is declared at compile-time. CORBA IDL does not include a similar array, but does include a sequence data type, which is similar in many respects to Vector, but requires compile-time type definition of its members. In many applications in which a Vector is used to pass an array of data all of the same type, it would be natural to map the Vector to a CORBA IDL sequence. However, because the Java program does not specify the data types of the members at compile-time (even though the programmer knows that they will always be of the same type), it is difficult to automate the mapping of the Vector to CORBA IDL sequence. As described in more detail below, in part to accommodate the weak typing of Vector, the Object Management Group Java-to-CORBA IDL mapping does not map Vector to IDL sequence, but uses a far more cumbersome mapping.
Another example involves the treatment of null values. Most Java data types support null values, whereas most CORBA IDL data types do not. As a result, data types that might otherwise map to one another cannot do so absent some method of handling null values at run-time.
Although we will discuss in considerable detail the problems with mapping Java interfaces to CORBA IDL, these problems are not restricted to CORBA IDL and Java. For example, some languages such as ML support type parameterization for generic programming, while others such as C++ support generic programming by representing generic structures using templates that must be instantiated to specific types before they are used. Run-time mapping between these structures may be required for interoperation.
As used in this document:
The term object means any software-defined computing entity.
The term client means any object that requests any service from another object.
The term server means any object that provides any service in response to a request from another object.
The term notation means any computer language or representation scheme that may be used to define or represent an interface of an object.
The term interface means any specification of the communication between two objects.
The term statically defined data structure means a data structure comprising one or more data types defined at compile-time, the types being incapable of variation during run-time.
The term dynamic data type means a data element comprising a data type that may varied at run-time.